import api from '@/http/index'
import { codeToText, textToCode } from '@/common/utils/address'

const SCRIPT_ID = 'hs-map-script'
let isLoaded = false
let loadPromise = null
let initialized = false

function loadScript() {
  if (!loadPromise) {
    loadPromise = new Promise(async (resolve, reject) => {
      try {
        const jsApiText = await api.map.jsApiProxy()
        const existingScript = document.getElementById(SCRIPT_ID)

        if (existingScript) {
          resolve()
          return
        }

        const script = document.createElement('script')
        script.id = SCRIPT_ID
        script.innerHTML = jsApiText
        isLoaded = true
        resolve()
        script.onerror = (e) => {
          reject(new Error('地图脚本加载失败'))
        }
        document.head.appendChild(script)
      } catch (error) {
        reject(error)
      }
    })
  }
  return loadPromise
}

function init() {
  if (!initialized) {
    initialized = true
    loadScript().catch(console.error)
  }
}

function beforeLoad(cb) {
  cb()
  init()
}

function loaded(cb) {
  init() // 确保总是先初始化
  if (isLoaded) {
    cb(window.BMapGL)
  } else {
    loadScript()
      .then(() => cb(window.BMapGL))
      .catch(console.error)
  }
}

// 将经纬度转换为地址
// lng 经度 lat 纬度
function decode(lng, lat) {
  return new Promise((resolve, reject) => {
    const geocoder = new window.BMapGL.Geocoder()
    geocoder.getLocation(new window.BMapGL.Point(lng, lat), (rs) => {
      if (rs) {
        const { city, district, province, street = '' } = rs.addressComponents
        const provinceCode = textToCode?.[province] || province
        let cityCode = textToCode?.[city] || city
        const districtCode = textToCode?.[district] || district
        // 判断是否直辖市
        if (provinceCode === cityCode) {
          cityCode = provinceCode + '01'
          // 重庆市特殊处理
          if (district.endsWith('县') && provinceCode === '50') {
            cityCode = provinceCode + '02'
          }
        }
        const formatAddress = `${provinceCode}/${cityCode}/${districtCode}/${street}${rs?.content?.poi_desc}`
        resolve(formatAddress)
      } else {
        reject(new Error('地址解析失败'))
      }
    })
  })
}

// 将地址转换为经纬度
// 标准格式地址 省/市/区/详细地址
function encode(address) {
  return new Promise((resolve, reject) => {
    const geocoder = new window.BMapGL.Geocoder()
    const [province, city, district, detail] = address.split('/')
    geocoder.getPoint(
      `${codeToText?.[province] || province}${codeToText?.[city] || city}${codeToText?.[district] || district}${detail}`,
      (point) => {
        if (point) {
          resolve(point)
        } else {
          reject(new Error('地址解析失败'))
        }
      },
      city,
    )
  })
}

export default {
  beforeLoad,
  loaded,
  encode,
  decode,
}
